﻿using SuperWebSocket;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SupWebSocketClientTest
{
    public partial class SocketClient : Form
    {
        OpenFileDialog openfile = new OpenFileDialog();

        SuperWebSocketClient client = new SuperWebSocketClient();         
        Dictionary<string, ProgressBarForm> ProgressBars = new Dictionary<string, ProgressBarForm>();

        public SocketClient()
        {
            InitializeComponent();
            InitializeControls();
        }

        private void InitializeControls()
        {
            client.ConsoleWrite.WriteType = WebSocketConsoleWriteType.console;

            client.OnConnected += new WebSocketEventHandler(OnClientConnected);
            client.OnLogined += new WebSocketEventHandler(OnClientLogined);
            client.OnMessage += new WebSocketEventHandler(OnReceiveMessage);
            client.OnImage += new WebSocketEventHandler(OnReceiveImage);
            client.OnLogout += new WebSocketEventHandler(OnClientLogout);
            client.OnClosed += new WebSocketEventHandler(OnClientClosed);
            client.OnError += new WebSocketEventHandler(OnClientError);
            client.OnBeginReceiveFile += new WebSocketEventHandler(OnBeginReceiveFile);
            client.OnFinishReceiveFile += new WebSocketEventHandler(OnFinishReceiveFile);
        }

        private void Message(DateTime Datetime,string Message)
        {
            if (this.MsgBox.InvokeRequired)
            {
                this.MsgBox.Invoke(new MethodInvoker(delegate () {
                    this.MsgBox.AppendText(Datetime.ToString("yyyy-MM-dd HH:mm:ss") + " " + Message+System.Environment.NewLine);
                }));
            }
            else
            {
                this.MsgBox.AppendText(Datetime.ToString("yyyy-MM-dd HH:mm:ss") + " " + Message + System.Environment.NewLine);
            }
        }

        private void Send()
        {
            int index = 0;
            string Message = this.txtSendContent.Text.Trim();
            for (; index < this.userList.Items.Count; index++)
            {
                if (this.userList.GetSelected(index))
                {
                    string Id = ((WebSocketSession)this.userList.Items[index]).Id;
                    if (Id != this.client.Id)
                        client.SendMessage(((WebSocketSession)this.userList.Items[index]).Id, Message);                        
                    this.Message(DateTime.Now, "你 对 " + GetWebSocketClientName(Id).Replace("你", "自己") + " 说：" + Message);
                }
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (btnConnect.Text == "连接")
                client.Connect(this.txtIpAddress.Text.Trim(), this.txtPort.Text.Trim(), this.txtUser.Text.Trim(), "123456", "chart", "32004");
            else
                client.Close();
        }

        private bool OnClientConnected(object sender, WebSocketEventArgs e)
        {
            btnConnect.Invoke(new MethodInvoker(() => { btnConnect.Text = "断开"; }));    
            return false;
        }

        private bool OnReceiveMessage(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketContextData)e.Data;
            Message(e.DateTime, GetWebSocketClientName(data.SendId) + " 对 " + GetWebSocketClientName(data.ReceiveId) + " 说：" + data.Data);
            return false;
        }

        private bool OnReceiveImage(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketContextData)e.Data;
            WebSocketImageData wsImageData=(WebSocketImageData)data.Data;

            this.Invoke(new MethodInvoker(delegate()
            {
                ReceivefileForm form = new ReceivefileForm(wsImageData.Name, wsImageData.Format, (byte[])wsImageData.Data);
                form.ShowDialog(this);
            }));          

            Message(e.DateTime, GetWebSocketClientName(data.SendId) + " 传来图片 " + wsImageData.Name + "." + wsImageData.Format + " 大小: " + wsImageData.ImageSize);
            return false;
        }

        private bool OnClientLogined(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketLoginResultData)((ContextData)e.Data).Data;
            if (data.client.Id == client.Id)
            {
                foreach (var user in data.clients)
                    this.userList.Invoke(new MethodInvoker(() => { this.userList.Items.Add(user); }));
            }
            else
            {
                this.userList.Invoke(new MethodInvoker(() => { this.userList.Items.Add(data.client); }));
            }
            return false;
        }

        private bool OnClientLogout(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketLoginResultData)((ContextData)e.Data).Data;
            this.userList.Invoke(new MethodInvoker(delegate() {
                foreach (WebSocketClientSession session in this.userList.Items)
                {
                    if (session.Id == data.client.Id)
                    {
                        this.userList.Items.Remove(session);
                        break;
                    }
                }
            }));            
            return false;
        }

        private bool OnClientClosed(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketLoginResultData)((ContextData)e.Data).Data;
            this.btnConnect.Invoke(new MethodInvoker(() => { btnConnect.Text = "连接"; }));
            this.userList.Invoke(new MethodInvoker(() => { this.userList.Items.Clear(); }));
            return false;
        }

        private bool OnClientError(object sender, WebSocketEventArgs e)
        {
            this.btnConnect.Invoke(new MethodInvoker(() => { btnConnect.Text = "连接"; }));
            Message(e.DateTime, e.Message);
            this.userList.Invoke(new MethodInvoker(delegate() {
                this.userList.Items.Clear();
            }));
            this.client.Close();
            return false;
        }

        private bool OnBeginReceiveFile(object sender, WebSocketEventArgs e)
        {
            bool result = false;
            WebSocketFileData data = (WebSocketFileData)e.Data;
            SaveFileDialog savefiledlg = new SaveFileDialog();
            savefiledlg.SupportMultiDottedExtensions = true;
            savefiledlg.FileName = data.Name + "." + data.Format;
            savefiledlg.DefaultExt = "*."+ data.Format;
            savefiledlg.Filter = "文件" + "|*." + data.Format;
            this.Invoke(new MethodInvoker(() => {
                if (savefiledlg.ShowDialog(this).Equals(DialogResult.OK))
                {
                    string Name = savefiledlg.FileName;
                    ProgressBarForm Form = new ProgressBarForm(data.Name + "." + data.Format, "收接中");
                    ProgressBars.Add(Name, Form);
                    data.ReceiveInfo = savefiledlg.FileName;
                    using (System.IO.FileStream fs = new System.IO.FileStream(data.ReceiveInfo, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
                    {
                        result = true;
                    }
                    Form.Show();
                    Form.Location = new Point(this.Left+(this.Width - Form.Width)/2,this.Top+ (this.Height - Form.Height) / 2);
                    Form.BringToFront();
                }
            }));
            return result;
        }

        private bool OnFinishReceiveFile(object sender, WebSocketEventArgs e)
        {
            WebSocketFileData data = (WebSocketFileData)e.Data;
            ProgressBars[data.ReceiveInfo].Close();
            return false;
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            Send();
        }

        private string GetWebSocketClientName(string Id)
        {
            string Name = string.Empty;
            var Session = this.client.Session;

            if (Id == this.client.Id)
            {
                Name = "你";
            }
            else if (Id == Session.ServerId)
            {
                Name = Session.ServerName;
            }
            else
            {
                if (this.userList.InvokeRequired)
                {
                    this.userList.Invoke(new MethodInvoker(() =>
                    {
                        foreach (WebSocketClientSession session in this.userList.Items)
                        {
                            if (session.Id == Id)
                            {
                                Name = session.Name;
                                break;
                            }
                        }
                    }));
                }
                else
                {
                    foreach (WebSocketClientSession session in this.userList.Items)
                    {
                        if (session.Id == Id)
                        {
                            Name = session.Name;
                            break;
                        }
                    }
                }
            }                      

            return Name;
        }

        private void 发送图片ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openfile.Filter = "jpg|*.jpg|png|*.png";
            if (openfile.ShowDialog(this).Equals(DialogResult.OK))
            {
                if (string.IsNullOrEmpty(openfile.FileName))
                    return;

                byte[] imageBuffer = null;
                System.IO.FileInfo fi = new System.IO.FileInfo(openfile.FileName);               
                using (System.IO.FileStream filestream = new System.IO.FileStream(fi.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    imageBuffer = new byte[filestream.Length];
                    filestream.Read(imageBuffer, 0, imageBuffer.Length);
                }

                string fileName = fi.Name;
                fileName = fileName.Substring(0, fileName.LastIndexOf('.'));
                string fileExtension = fi.Extension;
                fileExtension = fileExtension.Substring(1).ToLower().Trim();

                int index = 0;
                for (; index < this.userList.Items.Count; index++)
                {
                    if (this.userList.GetSelected(index))
                    {
                        string Id = ((WebSocketSession)this.userList.Items[index]).Id;
                        if (Id != this.client.Id)
                            client.SendImage(Id, fileName, fileExtension, imageBuffer);
                        this.Message(DateTime.Now, "你 对 " + GetWebSocketClientName(Id).Replace("你", "自己") + " 发送图片：" + fileName + "." + fileExtension + " 大小：" + client.GetBytesSize(imageBuffer.Length));
                    }
                }
            }
            
        }

        private void 发送文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

    }
}
